package com.sxpcwlkj.system.service.impl;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.sxpcwlkj.framework.config.LoginObject;
import com.sxpcwlkj.framework.config.properties.MsProperties;
import com.sxpcwlkj.framework.config.properties.TenantProperties;
import com.sxpcwlkj.common.code.entity.CaptchaEntity;
import com.sxpcwlkj.system.entity.SysTenant;
import com.sxpcwlkj.system.entity.SysUser;
import com.sxpcwlkj.system.entity.bo.LoginBodyBo;
import com.sxpcwlkj.common.exception.LoginException;
import com.sxpcwlkj.common.exception.TenantException;
import com.sxpcwlkj.system.mapper.SysUserMapper;
import com.sxpcwlkj.system.service.SysLoginService;
import com.sxpcwlkj.system.service.SysTenantService;
import com.sxpcwlkj.system.service.SysUserService;
import com.sxpcwlkj.common.utils.EncryptionUtil;
import com.sxpcwlkj.common.utils.RedisUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;

/**
 * @ClassName SysLoginServiceImpl
 * @Description TODO
 * @Author 西决
 * @Date 2022/12/25 12:06
 */
@RequiredArgsConstructor
@Service("sysLogin")
@Slf4j
public class SysLoginServiceImpl implements SysLoginService {

    private final SysTenantService sysTenantService;

    private final SysUserService sysUserService;

    private final SysUserMapper sysUserMapper;

    private final TenantProperties tenantProperties;

    private final MsProperties msProperties;


    @Override
    public String login(LoginBodyBo loginBodyBo) {


        //验证验证码
        verfyCaptcha(loginBodyBo.getUsername(), loginBodyBo.getCodeKey(), loginBodyBo.getCode(), loginBodyBo.getUuid());

        //验证租户
        verfyTenement(loginBodyBo.getTenantId());
        //用户名与密码验证
        SysUser sysUser = sysUserService.selectByUserName(loginBodyBo.getTenantId(), loginBodyBo.getUsername());
        // 效验
        if (null == sysUser) {
            throw new LoginException("账号不存在!");
        }
        // 账号是否禁用
        if (sysUser.getStatus() != 0) {
            throw new LoginException("账号已禁用!");
        }
        //解密数据库的密码
        String decryptRsa = EncryptionUtil.decryptAes(sysUser.getPassword(), sysUser.getAesKey());
        try {
            Assert.equals(loginBodyBo.getPassword(), decryptRsa);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new LoginException("账号与密码有误!");
        }
        //进行登记登记
        updateSysUser(sysUser);
        //根据用户id，进行登录
        StpUtil.login(sysUser.getUserId(), loginBodyBo.getRememberMe());

        // 获取当前会话的token值
        return StpUtil.getTokenValue();
    }

    @Override
    public void logout() {
        LoginObject.logout();
        //        try {
//            // 当前会话注销登录
//            StpUtil.logout();
//        } catch (NotLoginException ignored) {
//            throw new LoginException("Not Log In : " + ignored.getMessage());
//        }
    }


    /**
     * 验证码验证
     *
     * @param username
     * @param code
     * @param uuid
     */
    @Override
    public void verfyCaptcha(String username, String codeKey, String code, String uuid) {
        if(msProperties.getIsOpenCaptcha()){
            Map<String, Object> data = RedisUtil.getCacheObject(uuid);
            if (ObjectUtils.isEmpty(data)) {
                log.info("登录：验证码失效！");
                throw new LoginException("Verification code failure");
            }
            if (!codeKey.equals(data.get(CaptchaEntity.CODE.CAPTCHA_KEY.getValue()))) {
                log.info("登录：验证码与验证对象不匹配！");
                throw new LoginException("Verification code does not match the verification object");
            }
            if (!code.equalsIgnoreCase((String) data.get(CaptchaEntity.CODE.CAPTCHA_VALUE.getValue()))) {
                log.info("登录：验证码不匹配！");
                throw new LoginException("Verification code does not match");
            }
        }
        return;
    }

    /**
     * 验证租户
     *
     * @param tenantId
     */
    @Override
    public void verfyTenement(String tenantId) {
        if (tenantProperties.getEnable()) {
            //租户
            SysTenant sysTenant = sysTenantService.selectById(tenantId);
            if (ObjectUtils.isEmpty(sysTenant)) {
                log.info("登录租户：{} 不存在.", tenantId);
                throw new TenantException("tenant.not.exists");
            }
            if (sysTenant.getStatus() != 0) {
                log.info("登录租户：{} 状态为禁用.", tenantId);
                throw new TenantException("tenant off state");
            }
        }

    }

    @Override
    public void updateSysUser(SysUser sysUser) {
        sysUser.setLoginIp("172.0.0.1");
        sysUser.setLoginDate(new Date());
        sysUserMapper.updateById(sysUser);

    }


}
